﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Security.Permissions;
using System.Text;
using System.Windows.Forms;

using Be.Timvw.Framework.ComponentModel;

namespace VisualGTest.UI
{
    public class ResultsView : UserControl
    {
        private DataGridView dataGridView1 = new DataGridView();
        private ToolStrip toolStrip = new ToolStrip();
        private ToolStripProgressBar progressBar = new ToolStripProgressBar();

        public ResultsView()
        {
            InitializeComponent();
        }

        /// <summary> 
        /// Let this control process the mnemonics.
        /// </summary>
        [UIPermission(SecurityAction.LinkDemand, Window = UIPermissionWindow.AllWindows)]
        protected override bool ProcessDialogChar(char charCode)
        {
            // If we're the top-level form or control, we need to do the mnemonic handling
            if (charCode != ' ' && ProcessMnemonic(charCode))
            {
                return true;
            }
            return base.ProcessDialogChar(charCode);
        }

        /// <summary>
        /// Enable the IME status handling for this control.
        /// </summary>
        protected override bool CanEnableIme
        {
            get
            {
                return true;
            }
        }

        // HBC - cell resizing
        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex == -1)
            {
                return;
            }

            FailureInfoCell cell = dataGridView1.Rows[e.RowIndex]
                .Cells[e.ColumnIndex] as FailureInfoCell;

            if (cell != null)
            {
                cell.ShowingMessage = !cell.ShowingMessage;
                dataGridView1.AutoResizeRow(e.RowIndex);
            }
        }

        // HBC - make progress bar fill remaining space
        private void toolStrip1_Layout(System.Object sender, System.Windows.Forms.LayoutEventArgs e)
        {
            // http://stackoverflow.com/questions/2769087/how-to-make-a-toolstripcombobox-to-fill-all-the-space-available-on-a-toolstrip
            int width = toolStrip.DisplayRectangle.Width;

            foreach (ToolStripItem tsi in toolStrip.Items)
            {
                if (tsi != progressBar)
                {
                    width -= tsi.Width;
                    width -= tsi.Margin.Horizontal;
                }
            }

            progressBar.Width = Math.Max(0, width - progressBar.Margin.Horizontal);
        }

        private void InitializeComponent()
        {
            this.SuspendLayout();

            dataGridView1.AutoGenerateColumns = false;
            dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
            dataGridView1.AllowUserToAddRows = false;
            dataGridView1.AllowUserToDeleteRows = false;
            dataGridView1.AllowUserToResizeRows = false;
            dataGridView1.MultiSelect = false;
            dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            //dataGridView1.EditMode = DataGridViewEditMode.EditProgrammatically;
            //dataGridView1.AlternatingRowsDefaultCellStyle = new DataGridViewCellStyle()
            //{
            //    BackColor = Color.FromArgb(250, 240, 250)
            //};

            dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            dataGridView1.RowHeadersVisible = false;

            // HBC - attach events
            dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);

            var result1 = new TestResult("foo", "bar");
            var result2 = new TestResult("foo", "baz");
            var result3 = new TestResult("qux", "baz");
            var result4 = new TestResult("qux", "moo");

            result1.Status = TestResult.TestStatus.Success;
            result1.StartTime = DateTime.Now;
            result1.EndTime = result1.StartTime.AddMilliseconds(450);

            result2.Status = TestResult.TestStatus.Failure;
            result2.StartTime = result1.EndTime;
            result2.EndTime = result2.StartTime.AddSeconds(200).AddMilliseconds(320);
            result2.FailureInfo.FileName = "baz.cpp";
            result2.FailureInfo.LineNumber = 230;
            result2.FailureInfo.Summary = "Something went awry!";
            result2.FailureInfo.Message = "The\nStack\nTrace";

            result3.Status = TestResult.TestStatus.Success;
            result3.StartTime = result2.EndTime;
            result3.EndTime = result3.StartTime.AddMilliseconds(1200);

            result4.Status = TestResult.TestStatus.Started;
            result4.StartTime = result3.EndTime;

            SortableBindingList<DisplayableTestResult> results = new SortableBindingList<DisplayableTestResult>();

            results.Add(new DisplayableTestResult(result1));
            results.Add(new DisplayableTestResult(result2));
            results.Add(new DisplayableTestResult(result3));
            results.Add(new DisplayableTestResult(result4));

            dataGridView1.DataSource = results;

            //dataGridView1.SelectedRows
            //dataGridView1.AlternatingRowsDefaultCellStyle = new DataGridViewCellStyle();
            //dataGridView1.DoubleClick += foo
            // -->  DataGridViewCellEventArgs 

            DataGridViewColumn column;

            // checkbox column
            column = new DataGridViewCheckBoxColumn();
            column.DataPropertyName = "Selected";
            column.ReadOnly = false;  // HBC - editable!
            column.SortMode = DataGridViewColumnSortMode.Automatic;  // HBC - enable sorting
            column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.TopCenter;
            dataGridView1.Columns.Add(column);

            // remaining columns

            column = new DataGridViewImageColumn();
            column.DataPropertyName = "Status";
            column.Name = "Status";
            column.CellTemplate = new StatusCell();
            column.SortMode = DataGridViewColumnSortMode.Automatic;  // HBC - enable sorting
            column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.TopCenter;
            column.ReadOnly = true;
            dataGridView1.Columns.Add(column);

            column = new DataGridViewTextBoxColumn();
            column.DataPropertyName = "TestCaseName";
            column.Name = "Test Case";
            column.ReadOnly = true;
            column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.TopLeft;
            dataGridView1.Columns.Add(column);

            column = new DataGridViewTextBoxColumn();
            column.DataPropertyName = "TestName";
            column.Name = "Test";
            column.ReadOnly = true;
            column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.TopLeft;
            dataGridView1.Columns.Add(column);

            column = new DataGridViewTextBoxColumn();
            column.DataPropertyName = "StartTime";
            column.Name = "Start Time";
            column.ReadOnly = true;
            column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.TopCenter;
            dataGridView1.Columns.Add(column);

            column = new DataGridViewTextBoxColumn();
            column.DataPropertyName = "EndTime";
            column.Name = "End Time";
            column.ReadOnly = true;
            column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.TopCenter;
            dataGridView1.Columns.Add(column);

            column = new DataGridViewTextBoxColumn();
            column.DataPropertyName = "Duration";
            column.Name = "Duration";
            column.CellTemplate = new DurationCell();
            column.ReadOnly = true;
            column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.TopRight;
            dataGridView1.Columns.Add(column);

            column = new DataGridViewTextBoxColumn();
            column.DataPropertyName = "FailureInfo";
            column.Name = "Failure Info";
            column.CellTemplate = new FailureInfoCell();
            column.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            column.ReadOnly = true;
            dataGridView1.Columns.Add(column);

            // button panel
            toolStrip.AutoSize = false;
            toolStrip.Height = 30;
            toolStrip.Dock = DockStyle.Top;
            toolStrip.Layout += new LayoutEventHandler(toolStrip1_Layout);

            // combo-box
            ToolStripLabel comboLabel = new ToolStripLabel();

            comboLabel.Text = "Show:";
            toolStrip.Items.Add(comboLabel);

            ToolStripComboBox combo = new ToolStripComboBox();

            combo.DropDownStyle = ComboBoxStyle.DropDownList;
            combo.Size = new Size(120, 25);
            combo.Items.Add("[All]");
            combo.Items.Add("Failures Only");
            combo.SelectedIndex = 0;
            toolStrip.Items.Add(combo);

            // separator
            ToolStripSeparator sep = new ToolStripSeparator();
            toolStrip.Items.Add(sep);

            // buttons
            ToolStripSplitButton button;
            ToolStripDropDownMenu dropDown;

            dropDown = new ToolStripDropDownMenu();
            dropDown.Items.Add(new ToolStripMenuItem("Run All Tests"));
            dropDown.Items.Add(new ToolStripMenuItem("Run Selected Tests"));
            dropDown.Items.Add(new ToolStripMenuItem("Run Failed Tests"));

            button = new ToolStripSplitButton();
            button.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
            button.Image = VisualGTest.UI.Resources.Play;
            button.Text = "Run";
            button.DropDown = dropDown;
            toolStrip.Items.Add(button);

            dropDown = new ToolStripDropDownMenu();
            dropDown.Items.Add(new ToolStripMenuItem("Debug All Tests"));
            dropDown.Items.Add(new ToolStripMenuItem("Debug Selected Tests"));
            dropDown.Items.Add(new ToolStripMenuItem("Debug Failed Tests"));

            button = new ToolStripSplitButton();
            button.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
            button.Image = VisualGTest.UI.Resources.Play;
            button.Text = "Debug";
            button.DropDown = dropDown;
            toolStrip.Items.Add(button);

            ToolStripButton cancelButton = new ToolStripButton();
            cancelButton.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
            cancelButton.Image = VisualGTest.UI.Resources.Stop;
            cancelButton.Text = "Stop";
            toolStrip.Items.Add(cancelButton);

            // another separator
            toolStrip.Items.Add(new ToolStripSeparator());

            // progress bar
            progressBar.Maximum = 100;
            progressBar.Increment(75);
            progressBar.Style = ProgressBarStyle.Continuous;
            progressBar.ForeColor = Color.FromArgb(50, 220, 50);
            progressBar.AutoSize = false;
            progressBar.Height = 24;

            toolStrip.Items.Add(progressBar);

            // Initialize the form.
            dataGridView1.Dock = DockStyle.Fill;
            dataGridView1.BorderStyle = BorderStyle.None;

            this.Controls.Add(toolStrip);
            this.Controls.Add(dataGridView1);

            // HBC - change the z-order so the docking does not hide the title bar!
            dataGridView1.BringToFront();

            this.AutoSize = true;
            this.Text = "DataGridView object binding demo";

            this.ResumeLayout(false);
        }
    }
}
